package map.map

import android.graphics.Point
import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.MapPoi
import com.baidu.mapapi.map.MapStatus
import com.baidu.mapapi.map.MapStatusUpdateFactory
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.model.LatLngBounds
import com.baidu.mapapi.search.core.PoiInfo
import com.zjw.zy.base.publisher.DefaultPublisher
import com.zjw.zy.base.publisher.IPublisher
import com.zjw.zy.smi.JustWithIt
import com.zjw.zy.utils.AppUtils
import com.zjw.zy.utils.taskpool.TaskPool
import map.MapBaseManager
import map.constant.MapMode.MapModeDes
import map.ext.map
import map.utils.overlayutil.LineOverlay
import map.utils.overlayutil.LoverPoiOverlay
import map.utils.overlayutil.PoiOverlay
import map.utils.overlayutil.WalkingRouteOverlay

class MapManager : MapBaseManager() {

    //poi图层
    private val poiOverlay: PoiOverlay = PoiOverlay(AppUtils.getMapActivity().map())
    private val loverPoiOverlay: LoverPoiOverlay = LoverPoiOverlay(AppUtils.getMapActivity().map())
    private val lineOverlay: LineOverlay = LineOverlay(AppUtils.getMapActivity().map())

    //步行路线图层
    private val walkRouteOverlay: WalkingRouteOverlay =
        WalkingRouteOverlay(AppUtils.getMapActivity().map())

    private val mMapClickPublisher: IPublisher<BaiduMap.OnMapClickListener> = DefaultPublisher()
    private val mMapTouchPublisher: IPublisher<BaiduMap.OnMapTouchListener> = DefaultPublisher()
    private val mMapStatusPublisher: IPublisher<BaiduMap.OnMapStatusChangeListener> =
        DefaultPublisher()

    private val mapStatusChangeListener = object : BaiduMap.OnMapStatusChangeListener {
        override fun onMapStatusChangeStart(p0: MapStatus?) {
            mMapStatusPublisher.publish {
                it.onMapStatusChangeStart(p0)
            }
        }

        override fun onMapStatusChangeStart(p0: MapStatus?, p1: Int) {
            mMapStatusPublisher.publish {
                it.onMapStatusChangeStart(p0, p1)
            }
        }

        override fun onMapStatusChange(p0: MapStatus?) {
            mMapStatusPublisher.publish {
                it.onMapStatusChange(p0)
            }
        }

        override fun onMapStatusChangeFinish(p0: MapStatus?) {
            mMapStatusPublisher.publish {
                it.onMapStatusChangeFinish(p0)
            }
        }
    }

    private val mapClickListener = object : BaiduMap.OnMapClickListener {
        override fun onMapClick(p0: LatLng?) {
            mMapClickPublisher.publish {
                it.onMapClick(p0)
            }
        }

        override fun onMapPoiClick(p0: MapPoi?) {
            mMapClickPublisher.publish {
                it.onMapPoiClick(p0)
            }
        }
    }

    private val mapOnTouchListener = BaiduMap.OnMapTouchListener { ev ->
        mMapTouchPublisher.publish {
            it.onTouch(ev)
        }
    }

    fun addMapOnClickListener(observer: BaiduMap.OnMapClickListener) {
        mMapClickPublisher.subscribe(observer)
    }

    fun addMapOnTouchListener(observer: BaiduMap.OnMapTouchListener) {
        mMapTouchPublisher.subscribe(observer)
    }

    fun addMapStatusListener(observer: BaiduMap.OnMapStatusChangeListener) {
        mMapStatusPublisher.subscribe(observer)
    }

    fun removeMapOnClickListener(observer: BaiduMap.OnMapClickListener) {
        mMapClickPublisher.unsubscribe(observer)
    }

    fun removeMapOnTouchListener(observer: BaiduMap.OnMapTouchListener) {
        mMapTouchPublisher.unsubscribe(observer)
    }

    fun removeMapStatusChangeListener(observer: BaiduMap.OnMapStatusChangeListener) {
        mMapStatusPublisher.unsubscribe(observer)
    }

    fun addPoiOverLayClickListener(listener: JustWithIt<PoiInfo>) {
        poiOverlay.addPoiOverLayClickListener(listener)
    }

    fun removePoiOverLayClickListener(listener: JustWithIt<PoiInfo>) {
        poiOverlay.removePoiOverLayClickListener(listener)
    }

    fun poiOverLay() = poiOverlay

    fun loverOverLay() = loverPoiOverlay

    fun lineOverlay() = lineOverlay

    fun switchMapMode(@MapModeDes mode: Int) {
        TaskPool.main().post {
            AppUtils.getMapActivity().map().mapType = mode
        }
    }

    fun walkRouteOverlay() = walkRouteOverlay


    fun zoomIn() {
        AppUtils.getMapActivity().map().setMapStatus(
            MapStatusUpdateFactory.zoomIn()
        )
    }

    fun zoomOut() {
        AppUtils.getMapActivity().map().setMapStatus(
            MapStatusUpdateFactory.zoomOut()
        )
    }

    fun zoomBy(zoom: Float) {
        AppUtils.getMapActivity().map().setMapStatus(
            MapStatusUpdateFactory.zoomBy(zoom)
        )
    }

    fun zoomBy(bounds: List<LatLng>) {
        AppUtils.getMapActivity().map().setMapStatus(
            MapStatusUpdateFactory.newLatLngZoom(
                LatLngBounds.Builder().include(bounds).build(),
                100, 100, 100, 100
            )
        )
    }

    fun zoomBy(zoom: Float, point: Point) {
        AppUtils.getMapActivity().map().setMapStatus(
            MapStatusUpdateFactory.zoomBy(zoom, point)
        )
    }

    fun hideZoomButton() {
        AppUtils.getMapActivity().mapView().showZoomControls(false)
    }

    fun showZoomButton() {
        AppUtils.getMapActivity().mapView().showZoomControls(true)
    }

    fun mapDirectionMode() {

    }

    override fun onCreate() {
        map().apply {
            setOnMapClickListener(mapClickListener)
            setOnMapTouchListener(mapOnTouchListener)
            setOnMapStatusChangeListener(mapStatusChangeListener)
        }
    }

    override fun onDestroy() {
        map().apply {
            removeMapOnClickListener(mapClickListener)
            removeMapOnTouchListener(mapOnTouchListener)
            removeMapStatusChangeListener(mapStatusChangeListener)
        }
    }
}